<?php
/**
 * @link https://www.kancloud.cn/cleverstone/ymb2
 * @copyright Copyright (c) 2020 Yii Manager Software LLC
 */

namespace builder\helper;

use Yii;
use yii\di\Instance;
use yii\helpers\ArrayHelper;
use yii\db\QueryInterface;
use builder\widget\ajax\LinkPager;

/**
 * 应用
 * @author cleverstone
 * @since ym2.0
 */
class App
{
    /**
     * 获取应用程序参数
     * @param null $key
     * @param null $default 默认值
     * @return mixed
     */
    public static function params($key = null, $default = null)
    {
        $defaultParams = require dirname(__DIR__) . '/config/default.php';
        $appParams = Yii::$app->params;

        $params = ArrayHelper::merge($defaultParams, $appParams);
        if (!empty($key)) {
            return $params[$key] ?? $default;
        }

        return $params;
    }

    /**
     * 设置面包屑导航
     * @param array $params 面包屑导航配置项
     * - name 导航标签名
     * - url 完整链接或yii路由
     *
     * ```php
     * App::setViewBreadcrumb([
     *      ['name' => '首页'],
     *      ['name' => '积分列表','url' => 'admin/integral'],
     *      ['name' => '新增积分'],
     * ])
     * ```
     * @return true
     * @see H5::getViewBreadcrumb()
     */
    public static function setViewBreadcrumb(array $params)
    {
        Yii::$app->view->params['breadcrumb'] = $params;
        return true;
    }

    /**
     * 系统左侧菜单
     * @param array $options
     * @return string
     */
    public static function menu($options = [])
    {
        $widgetClass = App::params('admin.navMenu');
        if (class_exists($widgetClass)) {
            return $widgetClass::widget($options);
        }

        return '';
    }

    /**
     * 系统顶部导航
     * @param array $options
     * @return string
     */
    public static function nav($options = [])
    {
        $widgetClass = App::params('admin.topNav');
        if (class_exists($widgetClass)) {
            return $widgetClass::widget($options);
        }

        return '';
    }

    /**
     * RBAC管理器
     * @return \builder\base\RbacValidateInterface
     */
    public static function rbacManager()
    {
        $rbacManager = App::params('admin.rbacManager');
        return Instance::ensure($rbacManager, 'builder\base\RbacValidateInterface');
    }

    /**
     * 解析分页（用户HTML）
     * @param QueryInterface $query Db query instance
     * @param null|\Closure $callback A callable or closure
     * @return array
     * @throws \Throwable
     */
    public static function resolvePage(QueryInterface $query, $callback = null)
    {
        $countQuery = clone $query;
        $pagination = new \yii\data\Pagination([
            'totalCount' => $countQuery->count(),
            'pageSizeLimit' => [1, 500],
        ]);
        $pageStr = LinkPager::widget([
            'pagination' => $pagination,
        ]);

        $query->offset($pagination->offset)->limit($pagination->limit);
        $data = $query->all();
        if (is_callable($callback)) {
            $data = call_user_func($callback, $data);
        }

        return [$pageStr, $data];
    }

    /**
     * 分页查询（用于API）
     * @param QueryInterface $query Query db instance
     * @param null|callable $callback 分页数据回调
     * @return array
     */
    public static function queryPage(QueryInterface $query, $callback = null)
    {
        $countQuery = clone $query;
        $pagination = new \yii\data\Pagination([
            'totalCount' => $countQuery->count(),
            'pageSizeLimit' => [1, 50],
        ]);

        $data = $query->offset($pagination->offset)->limit($pagination->limit)->all();

        return [
            is_callable($callback) ? call_user_func($callback, $data) : $data,
            $pagination,
        ];
    }

    /**
     * 从表单数据中获取文件路径
     * @param array|\ArrayAccess $bodyParams 表单数据
     * @param string $paramsKey 参数字段
     * @param boolean $toArray 是否返回数组
     * @return array|string
     */
    public static function getFileLinkFromParams($bodyParams, $paramsKey, $toArray = false)
    {
        if (empty($bodyParams) || empty($bodyParams[$paramsKey])) {
            return $toArray ? [] : '';
        }

        $fileArray = $bodyParams[$paramsKey];
        $linkArray = ArrayHelper::getColumn($fileArray, 'link');
        if ($toArray) {
            return $linkArray;
        }

        if (count($linkArray) == 1) {
            return reset($linkArray);
        } else {
            return $linkArray;
        }
    }

    /**
     * 动态注册web资源包(按需调用)
     * @param array $assetNames 包名
     * @see \builder\bundle\CoreAsset::excludeAsset()
     *
     * @param null|callable $preInitHandler 预初始化处理函数
     * ```js
     * App::registerDynamicAsset(['highlight'], function () {
     *      //注册高亮web插件，并且初始化语言项和主题。
     *      \builder\bundle\Highlight::$supportLangs = ['json'];
     *      \builder\bundle\Highlight::$curTheme = 'base16/darktooth';
     * });
     * ```
     * @return void
     */
    public static function registerDynamicAsset(array $assetNames, $preInitHandler = null)
    {
        $viewParams = Yii::$app->view->params;
        $dynamicAssets = [];
        if (!empty($viewParams['__dynamic_assets'])) {
            $dynamicAssets = $viewParams['__dynamic_assets'];
        }

        foreach ($assetNames as $name) {
            if (!in_array($name, $dynamicAssets)) {
                $dynamicAssets[] = $name;
            }
        }

        Yii::$app->view->params['__dynamic_assets'] = $dynamicAssets;

        if (is_callable($preInitHandler)) {
            call_user_func($preInitHandler);
        }
    }
}